#include "WorldTest.h"

#include "../include/physicsworks.h"

CPPUNIT_TEST_SUITE_REGISTRATION(WorldTest);

using physicsworks::instanceUniverse;
using physicsworks::destroyUniverse;
using physicsworks::real;
using physicsworks::SpatialPartitioningType;
using physicsworks::NullSpatialPartitioningConfig;
using physicsworks::exception::BodyAlreadyAdded;
using physicsworks::exception::BodyAnotherWorld;
using physicsworks::exception::UnkownBody;
using physicsworks::exception::WorldBodyAlreadyAdded;

void WorldTest::setUp()
{
	universe = instanceUniverse();

	BodyMesh *monkeyMesh, *chairMesh;	
	monkeyMesh = new BodyMesh("tests/data/monkey.mesh.xml");
	chairMesh = new BodyMesh("tests/data/chair.mesh.xml");
	
	monkey = universe->instanceBody(monkeyMesh->vertX, monkeyMesh->vertY, monkeyMesh->vertZ, monkeyMesh->numVertices,
	                                monkeyMesh->verticesIndices, monkeyMesh->numFaces);
	delete monkeyMesh;
	
	chair = universe->instanceBody(chairMesh->vertX, chairMesh->vertY, chairMesh->vertZ, chairMesh->numVertices,
	                               chairMesh->verticesIndices, chairMesh->numFaces);
	delete chairMesh;
	
	sphere = universe->instanceSphereBody(0.3);
	cube = universe->instanceCubeBody(1);
	box = universe->instanceBoxBody(3, 1, 1);
	
	SpatialPartitioningType s = physicsworks::NULL_SPATIAL_PARTITIONING;
    NullSpatialPartitioningConfig sc;
	
	world0 = universe->instanceWorld(-300, -300, -300, 800, 700, 700, s, sc);
	world1 = universe->instanceWorld(-10, -10, -30, 80, 10, 70, s, sc);
	
}

void WorldTest::testAddingRemovingBodies()
{
	world0->add(monkey);
	CPPUNIT_ASSERT_THROW(world0->add(monkey), BodyAlreadyAdded);
	CPPUNIT_ASSERT_THROW(world0->remove(chair), UnkownBody);
	world0->remove(monkey);
	world0->add(monkey);
	world0->add(chair);
	
	world1->add(chair);
	universe->add(world0);
	CPPUNIT_ASSERT_THROW(universe->add(world1), WorldBodyAlreadyAdded);
	world1->remove(chair);
	universe->add(world1);
	CPPUNIT_ASSERT_THROW(world1->add(chair), BodyAnotherWorld);
	universe->removeAll();
	world0->removeAll();
	world1->removeAll();
}

void WorldTest::testGetBodiesList()
{
	int size;
	CPPUNIT_ASSERT(world0->getBodiesList(&size) == 0);
	
	world0->add(monkey);
	world0->add(chair);
	world0->remove(monkey);
	world0->add(cube);
	
	Body** bl = world0->getBodiesList(&size);
	CPPUNIT_ASSERT(size == 2);
	CPPUNIT_ASSERT( (bl[0] == chair && bl[1] == cube) ^ (bl[0] == cube && bl[1] == chair) );
	world0->removeAll();
	delete [] bl;
}

void WorldTest::tearDown()
{
	delete world0;
	delete world1;
	delete monkey;
	delete chair;
	delete cube;
	delete sphere;
	delete box;
	destroyUniverse();
}

